package gameEngine.agents.choosingStrategy;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import org.apache.log4j.Logger;


import gameEngine.agents.teamMateModel.AgentMock;
import gameEngine.agents.teamMateModel.TeamMateModel;

public class EGreedyStratagy implements ChoosingStrategy {

	Random generator=new Random();
	Logger log = Logger.getLogger(this.getClass());
	/**
	 * using a simple algorithm.
	 * if Epsilon Greedy < random number use exploitation
	 * else use exploration 
	 */
	public int chooseNextPlayer(TeamMateModel teamMateModel) {
		double eGreedy=teamMateModel.getSelf().getAgentEGreedy();
		double epsilon=generator.nextDouble();
		log.debug("random got "+epsilon+ " and agent "+teamMateModel.getSelf().getId()+
				" has EGreedy of: "+eGreedy);
		if(epsilon>eGreedy){
			log.debug("agent "+teamMateModel.getSelf().getId()+" selected best agent");
			return getBestAgent(teamMateModel);
		}else{
			log.debug("agent "+teamMateModel.getSelf().getId()+" selected exploration");
			return getRandomAgent(teamMateModel);
		}
	}
	
	/**
	 * sort team mate model and returns best one according to comperTO method of the AgentMock in model
	 * @param teamMateModel
	 * @return best agent id
	 */
	private int getBestAgent(TeamMateModel teamMateModel){
		ArrayList<AgentMock> agents=new ArrayList<AgentMock>();
		agents.addAll(teamMateModel.getTeamMates());
		//sorts in descending order
		Collections.sort(agents);
		int agent=agents.get(0).getId();
		log.debug("best agent is agent "+agent);
		return agent;
	}
	/**
	 * returns an id of a random agent except for best one
	 * @param teamMateModel
	 * @return random agent id
	 */
	private int getRandomAgent(TeamMateModel teamMateModel){
		ArrayList<AgentMock> agents=new ArrayList<AgentMock>();
		agents.addAll(teamMateModel.getTeamMates());
		//remove the best
		int bestID=getBestAgent(teamMateModel);
		for(int i=0;i<agents.size();i++){
			if(agents.get(i).getId()==bestID)
				agents.remove(i);
		}
		int rnd=generator.nextInt(agents.size());
		int agent=agents.get(rnd).getId();
		log.debug("random choose agent "+agent+" out of "+agents.size()+" agents");	
		return agent;
	}
	
	public EGreedyStratagy clone(){
		return new EGreedyStratagy();
	}
	
}
